﻿using System;
using System.ComponentModel;
using System.Xml.Serialization;
using T4UtilityBelt.DataDesigns;
using T4UtilityBelt.Serializers;
using T4UtilityBelt.UxDesigns.Controls.Renderers;
using T4UtilityBelt.UxDesigns.Interfaces;


namespace T4UtilityBelt.UxDesigns
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1005:AvoidExcessiveParametersOnGenericTypes")]
    public abstract class PropertyControl<TControl, TRenderer, TProperty> : Control<TControl, TRenderer>, IPropertyControl
        where TControl : PropertyControl<TControl, TRenderer, TProperty>
        where TRenderer : class, IPropertyRenderer<TControl, TRenderer, TProperty>
        where TProperty : Property
    {
        protected PropertyControl()
        {
        }

        protected PropertyControl(string propertyName)
        {
            PropertyName = propertyName;
        }

        protected PropertyControl(TProperty property)
        {
            this.Property = property;
            this.PropertyName = property.Name;
        }

        #region Properties

        public string PropertyName { get; set; }

        [XIgnore]
        public TProperty Property { get; set; }

        private bool? _readOnly;

        [DefaultValue(false)]
        public bool ReadOnly
        {
            get
            {
                if (_readOnly.HasValue)
                {
                    return _readOnly.Value;
                }
                if (Property != null)
                {
                    return Property.ReadOnly;
                }
                return true;
            }
            set { _readOnly = value; }
        }

        #endregion Properties

        #region Methods

        public override void FixModel(Entity entity)
        {
            base.FixModel(entity);
            Property = entity.Properties[PropertyName] as TProperty;
            if (Property == null)
            {
                throw new RenderException(string.Format("{0} of PropertyControl is not available in Entity {1}", PropertyName, entity.Name));
            }
        }

        #endregion Methods
    }
}